package com.hschinese.pronunciation.utils;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.Resources.NotFoundException;
import android.graphics.Paint;
import android.graphics.Paint.FontMetrics;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.support.v7.app.AlertDialog;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.text.format.DateFormat;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.hschinese.pronunciation.R;
import com.hschinese.pronunciation.activity.MyApplication;
import com.hschinese.pronunciation.activity.StudayChinesePracticeActivity;
import com.hschinese.pronunciation.activity.StudayREcognitionContentActivity;
import com.hschinese.pronunciation.interfaces.NextLessonInterface;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.Properties;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@SuppressLint("DefaultLocale")
public class Utils {

	/**
	 * 生成随机数
	 * @param min
	 * @param max
	 * @return
	 */
	public static int getRandon(int min, int max) {
		long randomNum = System.currentTimeMillis();
		int randon = (int) randomNum%(max-min)+min;
		Logger.e("xionghy - randon: " + randon);
		return Math.abs(randon);
	}

	/**
	 * 将一个字符串转换为骆驼命名格式 不能确定字符串是否为空时调用
	 *
	 * @param str
	 * @return
	 */
	@SuppressLint("DefaultLocale")
	public static String toCamelName(String str) {
		if (TextUtils.isEmpty(str))
			return str;
		if (str.length() < 2)
			return str.toLowerCase();
		return str.substring(0, 1).toLowerCase() + str.substring(1);
	}

	/**
	 * 将一个字符串转换为骆驼命名格式 能字符串长度大于1时使用
	 *
	 * @param str
	 * @return
	 */
	public static String toCamelCase(String str) {
		return str.substring(0, 1).toLowerCase() + str.substring(1);
	}

	/* Checks if external storage is available for read and write */
	public static boolean isExternalStorageWritable() {
		String state = Environment.getExternalStorageState();
		if (Environment.MEDIA_MOUNTED.equals(state)) {
			return true;
		}
		return false;
	}

	/* Checks if external storage is available to at least read */
	public static boolean isExternalStorageReadable() {
		String state = Environment.getExternalStorageState();
		if (Environment.MEDIA_MOUNTED.equals(state)
				|| Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
			return true;
		}
		return false;
	}

//	/**
//	 * 解压文件
//	 * 
//	 * @param path
//	 *            解压路径
//	 * @param fileName
//	 *            解压文件名（包含路径）
//	 */
//	public static void extractFile(String path, String fileName) {
//		try {
//			ZipFile zipFile = new ZipFile(fileName);
//			zipFile.extractAll(path);
//		} catch (ZipException e) {
//			e.printStackTrace();
//		}
//	}

	/**
	 * 下载文件
	 *
	 * @param urlStr
	 *            文件url
	 * @param destination
	 *            下载的目标文件夹
	 * @param fileName
	 *            下载后保存的文件名，直接写在destination中，此参数传空也可以
	 * @return
	 */
	public static boolean downloadFile(String urlStr, String destination,
									   String fileName) {
		InputStream inputStream = null;
		FileOutputStream fos = null;
		try {
			URL url = new URL(urlStr);
			URLConnection connection = url.openConnection();
			connection.connect();
			inputStream = connection.getInputStream();
			// 没有传文件名，认为将文件名写在destination参数中了，传了的话，需要加上文件名
			if (!TextUtils.isEmpty(fileName))
				destination = destination + File.separator + fileName;
			fos = new FileOutputStream(destination);
			byte[] buffer = new byte[1024];
			@SuppressWarnings("unused")
			int len = -1;
			while ((len = inputStream.read(buffer)) != -1) {
				fos.write(buffer);
			}
			return true;
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				if (inputStream != null)
					inputStream.close();
				if (fos != null)
					fos.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return false;
	}

	/**
	 * 返回设备语言
	 *
	 * @return {zh:中文（简繁体一样），ko:韩文，en:英文，ja:日文}
	 */
	public static String getLanguage(Context context) {
		String language = SharedPreferenceUtils.getInstance(context).getSharedKey(Constant.SYSTEM_LANGUAGE, Locale.getDefault().getLanguage());
		language = Constant.LANGUAGE_CHINESE.equals(language)?"zh-hans":language;
		return language;
	}

	/**
	 * md5加密
	 *
	 * @param plainText
	 * @return
	 */
	public static String encryptMD5(String plainText) {
		StringBuffer buf = new StringBuffer("");
		try {
			MessageDigest md = MessageDigest.getInstance("MD5");
			md.update(plainText.getBytes());
			byte b[] = md.digest();
			int i;
			for (int offset = 0; offset < b.length; offset++) {
				i = b[offset];
				if (i < 0)
					i += 256;
				if (i < 16)
					buf.append("0");
				buf.append(Integer.toHexString(i));
			}
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		return buf.toString();
	}

	/**
	 * 验证邮箱地址是否合法
	 *
	 * @param mailAddress
	 * @return
	 */
	public static boolean isEmailValid(String mailAddress) {
		if (TextUtils.isEmpty(mailAddress))
			return false;
		String check = "^[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}$";
		Pattern regex = Pattern.compile(check);
		Matcher matcher = regex.matcher(mailAddress);
		return matcher.matches();
	}

	/**
	 * 验证密码是否合法
	 *
	 * @param mailAddress
	 * @return
	 */
	public static boolean isPassWordValid(String mailAddress) {
		if (TextUtils.isEmpty(mailAddress))
			return false;
		String check = "[a-zA-Z0-9_]{6,16}";
		Pattern regex = Pattern.compile(check);
		Matcher matcher = regex.matcher(mailAddress);
		return matcher.matches();
	}

	/**
	 * 获取 AndroidManifest.xml中VersionCode
	 *
	 * @param context
	 * @return
	 */
	public static int getVersionCode(Context context) {
		try {
			PackageInfo pi = context.getPackageManager().getPackageInfo(
					context.getPackageName(), 0);
			return pi.versionCode;
		} catch (NameNotFoundException e) {
//			AppLogger.e("Utils.getVersionCode", "get version code failed");
			// Logger.e("get version code failed");
		}
		return 0;
	}

	/**
	 * 获取 AndroidManifest.xml中VersionCode
	 *
	 * @param context
	 * @return
	 */
	public static String getVersionName(Context context) {
		try {
			PackageInfo pi = context.getPackageManager().getPackageInfo(
					context.getPackageName(), 0);
			return pi.versionName;
		} catch (NameNotFoundException e) {
//			AppLogger.e("Utils.getVersionName", "get version name failed");
			// Logger.e("get version name failed");
		}
		return "";
	}

	/**
	 * 检测网络是否可用
	 *
	 * @return
	 */
	public static boolean isNetworkValid(Context _context) {
		ConnectivityManager connectivity = (ConnectivityManager) _context
				.getSystemService(Context.CONNECTIVITY_SERVICE);
		if (connectivity != null) {
			NetworkInfo[] info = connectivity.getAllNetworkInfo();
			if (info != null)
				for (int i = 0; i < info.length; i++)
					if (info[i].getState() == NetworkInfo.State.CONNECTED) {
						return true;
					}
		}
		return false;
	}

	/**
	 * 下载的数据中文件中包含的文件名称
	 *
	 * @param type
	 *            HSK等级与课程标志 两位数字，第一位为HSK等级，第二位为课程标志{听力：1，阅读：2，写作：3}
	 * @return
	 */
	private static String[] getFileNamesByLevelAndCourse(int type) {
		switch (type) {
			case 41: // 4级听力
				return new String[] { "introduction.xml", "practice.xml",
						"sentences.xml", "words.xml"};
			default:
				return null;
		}
	}

	/**
	 * 根据传入的课程表示获得需要的文件再与传入的文件文件名称数组进行对比，缺少文件的需要重新下载，是否需要下载文件 需要下载则返回true
	 *
	 * @param fileNames
	 *            存在的文件名称
	 * @return
	 */
	public static boolean needDownload(String[] fileNames) {
		if (fileNames == null || fileNames.length == 0)
			return true;
		String[] needs = new String[]{"introduction.xml", "practice.xml",
				"sentences.xml", "words.xml"}; //getFileNamesByLevelAndCourse(lacFlag);
		// 遍历两个数组，有不存在的文件名称则需要重新下载
		for (int i = 0; i < needs.length; i++) {
			boolean fileExist = false; // 文件是否存在
			for (int j = 0; j < fileNames.length; j++) {
				if (needs[i].equals(fileNames[j])) {
					fileExist = true;
					break;
				}
			}
			if (!fileExist) { // 有文件不存在则需要重新下载
				return true;
			}
		}
		return false;
	}

	/**
	 * 读配置文件
	 * @param key
	 * @return
	 */
	public static String readProperty(Context context, String key){
//		Log.e("readProperty key",key+"");
		String val = "";
		Properties prop = new Properties();
		InputStream is = null;
		try {
			is = context.getAssets().open("config.properties"); //打开配置文件流
			prop.load(is);
			return prop.getProperty(key);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally{
			if(is!=null){
				try {
					is.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return val;
	}

	/**
	 * 安装新的 apk
	 * @param activity
	 * @param result
	 * @param fileName
	 */
	public static void installApk(Activity activity, Long result, String fileName){
		if(result>0){
			File file = new File(fileName);
			Intent intent = new Intent();
			//执行动作     
			intent.setAction(Intent.ACTION_VIEW);
			//执行的数据类型     
			intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");//编者按：此处Android应为android，否则造成安装不了
			activity.startActivity(intent);
		} else if(!TextUtils.isEmpty(fileName)){
			UIUtils.showToast(activity, activity.getString(R.string.error_download_failed), Toast.LENGTH_SHORT);
		}
	}


	/**
	 * 获得竖向的dp值
	 * @param context
	 * @return
	 */
	public static int getHeightPx(Context context){
		return context.getResources().getDisplayMetrics().heightPixels;
	}

	public static void setListViewHeightBasedOnChildren(ListView listView) {
		ListAdapter listAdapter = listView.getAdapter();
		if (listAdapter == null) {
			// pre-condition 
			return;
		}
		int totalHeight = 0;
		for (int i = 0; i < listAdapter.getCount(); i++) {
			View listItem = listAdapter.getView(i, null, listView);
			listItem.measure(0, 0);
			totalHeight += listItem.getMeasuredHeight();
		}

		ViewGroup.LayoutParams params = listView.getLayoutParams();
		params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
		listView.setLayoutParams(params);
	}

	/**
	 * 将一个View设为不可用状态
	 * @param view
	 * @param context
	 */
	public static void disableView(View view, Context context){
		view.setClickable(false);
		((TextView)view).setTextColor(context.getResources().getColor(R.color.light_black));
	}

	/**
	 * 递归删除文件
	 * @param file
	 */
	public static boolean recursiveDel(File file){
		if(file.exists()){
			if(file.isDirectory()){
				for(File item:file.listFiles()){
					recursiveDel(item);
				}
				file.delete();
			}else if(file.isFile()){
				file.delete();
			}
			return true;
		}
		return false;
	}



	/**
	 * 获得文本高度
	 * @param fontSize
	 * @return
	 */
	public static float getFontHeight(float fontSize){
		Paint paint = new Paint();
		paint.setTextSize(fontSize);
		FontMetrics fm = paint.getFontMetrics();
		return  (float) Math.ceil(fm.descent - fm.top) + 2;//Math.ceil(fm.descent - fm.ascent);
	}

	/**
	 * 获得时间戳
	 * @return
	 */
	public static Long getTimestamp(){
		Calendar mCalendar = Calendar.getInstance();
		return mCalendar.getTimeInMillis()/1000;
	}

	/**
	 * 解析 时间戳为指定格式
	 * @param timeInMillis
	 * @return
	 */
	public static String formatTimeStamp(Long timeInMillis){
		Calendar mCalendar = Calendar.getInstance();
		mCalendar.setTimeInMillis(timeInMillis);
		StringBuffer timeStamp = new StringBuffer(DateFormat
				.format("yyyy-MM-dd hh:mm", mCalendar).toString());
		timeStamp.append(mCalendar.get(Calendar.AM_PM)==0?" AM":" PM");
		return timeStamp.toString();
	}

	/**
	 * 解析 时间戳为指定格式
	 * @param timeInMillis
	 * @return
	 */
	@SuppressLint("SimpleDateFormat")
	public static String formatSystemTimeStamp(Long timeInMillis){
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm");
		String timeStamp = format.format(new Date(timeInMillis * 1000));
		return timeStamp.toString();
	}

	/**
	 * 当用户设置了语言时使用用户设置的语言作为app语言，这里与android系统语言需要做区分
	 * @param context
	 */
	public static void setLanguage(Context context){
		SharedPreferenceUtils sp = SharedPreferenceUtils.getInstance(context);
		String language = sp.getSharedKey(Constant.SYSTEM_LANGUAGE, null);
		if(!TextUtils.isEmpty(language) && !language.equals(Locale.getDefault().getLanguage())){
			Configuration config = context.getResources().getConfiguration();
			DisplayMetrics dm = context.getResources().getDisplayMetrics();
			config.locale = Locale.ENGLISH;
			if(Constant.LANGUAGE_JAPANESE.equals(language))
				config.locale = Locale.JAPANESE;
			else if(Constant.LANGUAGE_KOREAN.equals(language))
				config.locale = Locale.KOREAN;
			else if(Constant.LANGUAGE_CHINA.equals(language))
				config.locale = Locale.CHINESE;
			context.getResources().updateConfiguration(config, dm);
		}
	}

	/**
	 * 获得机器码
	 * @return
	 */
	public static String getUniqueCode(Context ctx){
		TelephonyManager tm = (TelephonyManager) ctx.getSystemService(Context.TELEPHONY_SERVICE);
		String tmDevice, tmSerial, androidId;
		tmDevice = "" + tm.getDeviceId();
		tmSerial = "" + tm.getSimSerialNumber();
		androidId = "" + android.provider.Settings.Secure.getString(ctx.getContentResolver(), android.provider.Settings.Secure.ANDROID_ID);
		UUID deviceUuid = new UUID(androidId.hashCode(), ((long)tmDevice.hashCode() << 32) | tmSerial.hashCode());
		return deviceUuid.toString();
	}

	public static void killBackProcess(){
		ActivityManager am = (ActivityManager) MyApplication.getInstance().getSystemService(Context.ACTIVITY_SERVICE);
		try {
			Method forceStopPackage = am.getClass().getDeclaredMethod("forceStopPackage", String.class);
			forceStopPackage.setAccessible(true);
			System.out.println("activity: " + MyApplication.getInstance().getPackageName());
			forceStopPackage.invoke(am, MyApplication.getInstance().getPackageName());
			am.killBackgroundProcesses(MyApplication.getInstance().getPackageName());
			System.gc();
		}
		catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static String getDeviceName() {
		String manufacturer = Build.MANUFACTURER;
		String model = Build.MODEL;
		if (model.startsWith(manufacturer)) {
			return capitalize(model);
		} else {
			return capitalize(manufacturer) + " " + model;
		}
	}


	public static String capitalize(String s) {
		if (s == null || s.length() == 0) {
			return "";
		}
		char first = s.charAt(0);
		if (Character.isUpperCase(first)) {
			return s;
		} else {
			return Character.toUpperCase(first) + s.substring(1);
		}
	}

	/**
	 *
	 * @param maxWidth  录音条最长宽度
	 * @param time      时间
	 * @param per       每px占多少秒
	 * @return
	 */
	public static int getCommunityVoiceWidth(int maxWidth,int minWidth,long time,float per){
		int width = (int) (time*per);
		width = width>maxWidth?maxWidth:width;
		width = width<minWidth?minWidth:width;
		return width;
	}

	public static String getPlayTimeByMil(long timeMillisecond){
		StringBuffer timeStr = new StringBuffer();
		long time = timeMillisecond/60;
		if(time>1){
			timeStr.append(time).append("＇").append(timeMillisecond-time*60).append("＂");
		}else{
			timeStr.append(timeMillisecond).append("＂");
		}
		return timeStr.toString();
	}

	public static String GetFormatTime(int time) {
		SimpleDateFormat sim = new SimpleDateFormat("mm:ss");
		return sim.format(time);
	}

	/**
	 * 解析 时间戳为指定格式
	 * @param timeInMillis
	 * @return
	 */
	public static String formatTimeStamp(Long timeInMillis,String format){
		Calendar mCalendar = Calendar.getInstance();
		mCalendar.setTimeInMillis(timeInMillis);
		String timeStamp = DateFormat.format(format, mCalendar).toString();
		return timeStamp;
	}

	/**
	 * 获取内部版本号
	 * @param cxt
	 * @return
	 */
	public static String getInnerVersionNo(Context cxt) {
		String s = "";
		PackageManager manager = cxt.getPackageManager();
		try {
			PackageInfo info = manager.getPackageInfo(cxt.getPackageName(), 0);
			s = info.versionName;
		} catch (NameNotFoundException e) {
			e.printStackTrace();
		}
		return s;
	}

	public static int getResId(Context cxt, String name, String defType) {
		String packageName = cxt.getApplicationInfo().packageName;
		Resources mResources = cxt.getResources();
		return mResources.getIdentifier(name, defType, packageName);
	}

	public static void showDialog(final Activity cxt, int tipStringId, final int lesson, final NextLessonInterface listener ) {
		AlertDialog.Builder mDialog;
		mDialog = new AlertDialog.Builder(cxt);
		mDialog.setMessage(cxt.getResources().getString(tipStringId));
		mDialog.setPositiveButton(cxt.getResources().getString(R.string.btn_confirm), new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				// TODO Auto-generated method stub
				// TODO 进入下一课. 会掉到StudyActivity页面来进行View的切换
				listener.onLessonChanged(lesson + 1);
				if(lesson==15){
					cxt.finish();

				}else if(lesson==14){
					cxt.startActivity(new Intent(cxt,StudayChinesePracticeActivity.class).putExtra("type",15));

				}else if(lesson==13){
					cxt.startActivity(new Intent(cxt,StudayREcognitionContentActivity.class).putExtra("lesson",4).putExtra("position",0));

				}
			}
		});
		mDialog.setNegativeButton(cxt.getResources().getString(R.string.btn_cancel), new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				cxt.finish();
			}
		});
		mDialog.create().show();
	}

	public static String delHTMLTag(String htmlStr){
		String regEx_script="<script[^>]*?>[\\s\\S]*?<\\/script>"; //定义script的正则表达式
		String regEx_style="<style[^>]*?>[\\s\\S]*?<\\/style>"; //定义style的正则表达式
		String regEx_html="<[^>]+>"; //定义HTML标签的正则表达式

		Pattern p_script=Pattern.compile(regEx_script,Pattern.CASE_INSENSITIVE);
		Matcher m_script=p_script.matcher(htmlStr);
		htmlStr=m_script.replaceAll(""); //过滤script标签

		Pattern p_style=Pattern.compile(regEx_style,Pattern.CASE_INSENSITIVE);
		Matcher m_style=p_style.matcher(htmlStr);
		htmlStr=m_style.replaceAll(""); //过滤style标签

		Pattern p_html=Pattern.compile(regEx_html,Pattern.CASE_INSENSITIVE);
		Matcher m_html=p_html.matcher(htmlStr);
		htmlStr=m_html.replaceAll(""); //过滤html标签
		return htmlStr.trim(); //返回文本字符串
	}
}
